package com.zhaopin.lambda;

import com.google.common.base.Function;
import org.apache.poi.ss.formula.functions.T;
import reactor.core.Scannable;

import java.security.PrivilegedAction;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.*;
import java.util.stream.Collectors;

/**
 * @author yin.peide
 * @date 2021-11-02 9:34
 * <p>
 * Java 8实战
 */
public class App {

    public static void main(String[] args) {

        java.util.function.Function<Integer,Integer> ff = x -> (x + 1);
        java.util.function.Function<Integer,Integer> dd = x -> (x * 2);


        java.util.function.Function<Integer,Integer> mm = x -> x;



        java.util.function.Function<Integer, Integer> integerIntegerFunction = ff.compose(dd);
        System.out.println(integerIntegerFunction.apply(3));

        List<String> listQ = Arrays.asList("a", "b", "A", "B");
        listQ.sort(String::compareToIgnoreCase);
        System.out.println(listQ);

        List<String> list = new ArrayList<>();
        list.add("abc");
        list.add("efg");

        java.util.function.Function<String, Integer> funct1 = (String s) -> Integer.parseInt(s);
        java.util.function.Function<String, Integer> funct2 = Integer::parseInt;

        BiPredicate<List<String>, String> listPredicate = (List<String> list1, String element) -> list1.contains(element);

        BiPredicate<List<String>, String> listPredicate2 = List::contains;
        BiFunction<List<String>, String, Boolean> listPredicate3 = List::contains;

        // 构造函数


        /*List list1 = filter(list, t -> t.equals("efg"));
        System.out.println(list1);*/

        /*forEach(list,t -> System.out.println(t));*/

        List<String> list2 = map(list, t -> t + "11");
        System.out.println(list2);

        Callable<Integer> c = () -> 1;
        PrivilegedAction<Integer> a = () -> 2;

        Predicate<String> p = s -> list.add(s);


        Consumer<String> b = s -> list.add(s);

        String abc = "1234";

        com.google.common.base.Function<String, Integer> parsetInt = Integer::parseInt;
        com.google.common.base.Function<String, String> stringStringFunction = String::toUpperCase;
        Function<String, String> func = t -> t.toUpperCase();

        Function<String, String> func2 = String::toLowerCase;
        java.util.function.Function<String, String> stringStringFunction1 = String::toUpperCase;

//        java.util.function.Consumer runnable = System.out::println;
//        BiFunction<String, Integer, String> str = String::substring;
//        BiFunction<String, Integer, String> str1 = (s,i) -> s.substring(i);
//        Object o = () -> {System.out.println("1243");}

        Supplier<Apple> appleSupplier = Apple::new;
        Apple apple = appleSupplier.get();
        System.out.println(apple);

    }

    static interface Runnable<T> {
        void run();
    }


    //写一个map方法
    public static <T, R> List<R> map(List<T> list, Function<T, R> function) {
        List<R> results = new ArrayList<>();
        for (T t : list) {
            results.add(function.apply(t));
        }
        return results;

    }

    //最后再来个function 模拟就模拟到底
    static interface Function<T, R> {
        R apply(T t);
    }

    static interface Predicate<T> {
        boolean test(T t);
    }

    public static <T> List<T> filter(List<T> list, Predicate<T> p) {
        List<T> results = new ArrayList<>();
        for (T s : list) {
            if (p.test(s)) {
                results.add(s);
            }
        }
        return results;
    }

    static interface Consumer<T> {
        void accept(T t);
    }

    public static <T> void forEach(List<T> list, Consumer<T> c) {
        for (T t : list) {
            c.accept(t);
        }
    }


    public static void process(Runnable r) {
        r.run();
    }

    public Callable<String> fetch() {
        return () -> "123";
    }

    static class Apple {
        String weight;

        public String getWeight() {
            return weight;
        }

        public void setWeight(String weight) {
            this.weight = weight;
        }
    }
}

